package com.test.socket;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.util.Iterator;

public class TCPServerSelector {
	private static final int BUFSIZE = 256; // Buffer size (bytes)
	private static final int TIMEOUT = 3000; // wait timeout (milliseconds)

	public static void main(String[] args) throws IOException {
		// create a selector to multiplex listening sockets and connections
		Selector selector = Selector.open();
		// create listening socket channel for each port and register selector
		//for (String arg : args) {
			ServerSocketChannel listnChannel = ServerSocketChannel.open();
			listnChannel.socket().bind(
					new InetSocketAddress(8086));
			listnChannel.configureBlocking(false);// must be nonblocking to
													// register
			// register selector with channel ,the returned key is ignored
			listnChannel.register(selector, SelectionKey.OP_ACCEPT);
		//}
		// create a handler that will implement the protocol
		TCPProtocol protocol = new EchoSelectorProtocol(BUFSIZE);
		while (true) {// run forever,processing available i/o operations
			// wait for some channel to be ready(or timeout)
			//
			if (selector.select(TIMEOUT) == 0) {// return # of ready channels
				System.out.print(".");
				continue;
			}
			// get iterator on set of keys with i/o to process
			Iterator<SelectionKey> keyIterator = selector.selectedKeys()
					.iterator();
			while (keyIterator.hasNext()) {
				SelectionKey key = keyIterator.next();// key is bit mask
				// server socket channel has pending connection requests?
				if (key.isAcceptable()) {
					protocol.handleAccept(key);
				}
				// client socket channel has pending data?
				if (key.isReadable()) {
					protocol.handleRead(key);
				}
				// client socket channel is available for writing and
				// key is valid (i.e.,channel not closed)?
				if (key.isValid() && key.isWritable()) {
					protocol.handleWrite(key);
				}
				keyIterator.remove();// remove from set of selected keys
			}

		}
	}
}
